package indi.bamboo.demo.config.druid;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * package:    com.zoshine.wsyypt.config.druid
 * class_name: DruidAutoConfiguration
 * describe:   druid自动配置
 * Copyright:  Copyright (c) 2012-2018 All Rights Reserved.
 * Company:    zoshine.com Inc.
 *
 * @author libw
 * @version 1.0
 * create_time: 2017/12/4 ,9:07
 */
@Configuration
@EnableConfigurationProperties(DruidProperties.class)
@ConditionalOnClass(DruidDataSource.class)
@ConditionalOnProperty(prefix = "druid", name = "url")
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
public class DruidAutoConfiguration {
    @Resource
    private DruidProperties druidProperties;

    @Bean
    public WallConfig wallConfig() {
        WallConfig wallConfig = new WallConfig();
        wallConfig.setMultiStatementAllow(true);
        return wallConfig;
    }

    @Bean
    public WallFilter wallFilter() {
        WallFilter wallFilter = new WallFilter();
        wallFilter.setConfig(wallConfig());
        return wallFilter;
    }

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(druidProperties.getDriverClassName());
        dataSource.setUrl(druidProperties.getUrl());
        dataSource.setUsername(druidProperties.getUsername());
        dataSource.setPassword(druidProperties.getPassword());
        dataSource.setInitialSize(druidProperties.getInitialSize());
        dataSource.setMaxActive(druidProperties.getMaxActive());
        dataSource.setMinIdle(druidProperties.getMinIdle());
        dataSource.setMaxWait(druidProperties.getMaxWait());
        dataSource.setPoolPreparedStatements(druidProperties.isPoolPreparedStatements());
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(druidProperties.getMaxPoolPreparedStatementPerConnectionSize());
        dataSource.setValidationQuery(druidProperties.getValidationQuery());
        dataSource.setValidationQueryTimeout(druidProperties.getValidationQueryTimeout());
        dataSource.setTestOnBorrow(druidProperties.isTestOnBorrow());
        dataSource.setTestOnReturn(druidProperties.isTestOnReturn());
        dataSource.setTestWhileIdle(druidProperties.isTestWhileIdle());
        dataSource.setTimeBetweenEvictionRunsMillis(druidProperties.getTimeBetweenEvictionRunsMillis());
        dataSource.setMinEvictableIdleTimeMillis(druidProperties.getMinEvictableIdleTimeMillis());
        dataSource.setConnectionProperties(druidProperties.getConnectionProperties());
        dataSource.setUseGlobalDataSourceStat(druidProperties.isUseGlobalDataSourceStat());

        List<Filter> filterList = new ArrayList<>();
        String filters = druidProperties.getFilters();
        String[] filterArray = filters.split(",");
        for (String filter : filterArray) {
            switch (filter) {
                case "wall":
                    WallFilter wallFilter = new WallFilter();
                    WallConfig wallConfig = new WallConfig();
                    wallConfig.setMultiStatementAllow(druidProperties.isMultiStatementAllow());
                    wallFilter.setConfig(wallConfig);
                    filterList.add(wallFilter);
                    break;
                case "stat":
                    StatFilter statFilter = new StatFilter();
                    filterList.add(statFilter);
                    break;
                default:
            }
        }
        dataSource.setProxyFilters(filterList);
        try {
            dataSource.init();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return dataSource;
    }
}
